package com.iplant.basic.serviceImpl;

import com.iplant.base.po.APIResult;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.RetCode;
import com.iplant.base.utils.SessionConstants;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.DesUtil;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.remote.RemoteInvokeUtils;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.basic.service.BFCService;
import com.iplant.basic.service.BPMService;
import com.iplant.basic.service.basicenum.bfc.BFCMessageStatus;
import com.iplant.basic.service.basicenum.bfc.BFCMessageType;
import com.iplant.basic.service.basicenum.bpm.BPMEventModule;
import com.iplant.basic.service.basicenum.bpm.BPMHistoryTaskStatus;
import com.iplant.basic.service.bpm.BPMTaskService;
import com.iplant.basic.service.po.bfc.BFCHandleTaskMessage;
import com.iplant.basic.service.po.bfc.BFCMessage;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.bms.qft.BMSPersonQualification;
import com.iplant.basic.service.po.bpm.BPMActivitiHisTask;
import com.iplant.basic.service.po.bpm.BPMActivitiTask;
import com.iplant.basic.service.po.bpm.BPMTaskBase;
import com.iplant.basic.service.po.bpm.BPMUser;
import com.iplant.basic.serviceImpl.dao.bfc.BFCMessageDAO;
import com.iplant.basic.serviceImpl.dao.bpm.BPMUserDAO;
import com.iplant.basic.utils.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Femi
 * 2019年12月27日12:46:35
 */
@Service
public class BPMServiceImpl implements BPMService {

    private static final Logger logger = LoggerFactory.getLogger(BPMServiceImpl.class);

    public BPMServiceImpl() {
    }

    private static BPMService Instance;

    public static BPMService getInstance() {
        if (Instance == null)
            Instance = new BPMServiceImpl();
        return Instance;
    }

    //region POService
    PoService<BPMUser> mBPMUserService = ORMUtils.GetPoService(BPMUser.class);
    PoService<BMSEmployee> mBMSEmployeeService = ORMUtils.GetPoService(BMSEmployee.class);
    //endregion

    @Override
    public APIResult BPM_CreateProcess(BMSEmployee wLoginUser, BPMEventModule wModule, int wSheetID, Object wData) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processDefinitionKey", "_" + wModule.getValue());
            wParams.put("BusinessKey", wSheetID + "");

            if (wData == null) {
                wData = new HashMap<String, Object>();
            }
            Map<String, Object> wMap = CloneTool.Clone(wData, Map.class);
            for (String wKey : wMap.keySet()) {
                wMap.putIfAbsent(wKey, "");
                if (wMap.get(wKey).getClass().isArray()) {
                    wMap.put(wKey, StringUtils.Join(",", (Object[]) wMap.get(wKey)));
                }
                if (wMap.get(wKey) instanceof Collection<?>) {
                    wMap.put(wKey, StringUtils.Join(",", (Collection<?>) wMap.get(wKey)));
                }
            }

            wParams.put("data", wMap);
            if (wMap.containsKey("Code")) {
                wParams.put("processInstanceCode", wMap.get("Code"));
                if (!wMap.containsKey("processInstanceCode"))
                    wMap.put("processInstanceCode", wMap.get("Code"));
            }

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/startProcessByProcessDefinitionKey?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.POST);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_CompleteTask(BMSEmployee wLoginUser, int wTaskID, int wLocalScope, Object wData) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("TaskID", wTaskID + "");
            wParams.put("localScope", wLocalScope);

            if (wData == null) {
                wData = new HashMap<String, Object>();
            }

            Map<String, Object> wMap = CloneTool.Clone(wData, Map.class);
            for (String wKey : wMap.keySet()) {
                wMap.putIfAbsent(wKey, "");
                if (wMap.get(wKey).getClass().isArray()) {
                    wMap.put(wKey, StringUtils.Join(",", (Object[]) wMap.get(wKey)));
                }
                if (wMap.get(wKey) instanceof Collection<?>) {
                    wMap.put(wKey, StringUtils.Join(",", (Collection<?>) wMap.get(wKey)));
                }
                if (wMap.get(wKey) instanceof Integer) {
                    wMap.put(wKey, StringUtils.parseString(wMap.get(wKey)));
                }
            }

            wParams.put("data", wMap);
            if (wMap.containsKey("Code"))
                wParams.put("processInstanceCode", wMap.get("Code"));

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/CompleteMyPersonalTask?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.POST);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetTask(BMSEmployee wLoginUser, int wTaskID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("taskId", wTaskID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiHisTaskByTaskId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_CurrentTask(BMSEmployee wLoginUser, int wProcessInstanceID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processInstanceId", wProcessInstanceID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Leave/CurrentTask?cadv_ao={0}&cade_po={1}", wLoginUser.getLoginName(),
                            wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetOperationByTaskID(BMSEmployee wLoginUser, int wTaskID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("taskId", wTaskID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Repository/getNextSFConditionByTaskId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetTaskListByInstance(BMSEmployee wLoginUser, int wInstanceID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processInstanceId", wInstanceID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/getUnfinishedTaskByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    /**
     * 提交BPM 并创建代办
     *
     * @param wLoginUser
     * @param wTaskID
     * @param wLocalScope
     * @param wBPMTaskBase
     * @param wData
     * @return
     */
    @Override
    public ServiceResult<Boolean> BPM_MsgUpdate(BMSEmployee wLoginUser, int wTaskID, int wLocalScope,
                                                BPMTaskBase wBPMTaskBase, Object wData) {
        ServiceResult<Boolean> wResult = new ServiceResult<>(false);
        try {
            APIResult wAPIResult = BPM_CompleteTask(wLoginUser, wTaskID, wLocalScope, wData);

            if (wAPIResult.getResultCode() != RetCode.SERVER_CODE_SUC) {
                wResult.FaultCode += "BPM_CompleteTask ERROR:" + wAPIResult.getResultCode() + " Msg:" + wAPIResult.getMsg();
                return wResult;
            }

            BPMActivitiHisTask wHisTask = BPM_GetTask(wLoginUser, wTaskID).Info(BPMActivitiHisTask.class);
            if (wHisTask == null || StringUtils.isEmpty(wHisTask.ID)) {
                wResult.FaultCode += "任务不存在！";
                return wResult;
            }
            if (wHisTask.Status != BPMHistoryTaskStatus.NomalFinished.getValue()) {
                return wResult;
            }

            BPMActivitiTask wSelfTask = BPM_GetTask(wLoginUser, wTaskID).Info(BPMActivitiTask.class);
            if ((wSelfTask == null) || (StringUtils.isEmpty(wSelfTask.ID))
                    || (wTaskID != StringUtils.parseInt(wSelfTask.ID))) {
                wResult.Result = Boolean.TRUE;
                wResult.FaultCode += "任务不存在！";
                return wResult;
            }

            List<BPMActivitiTask> wBPMActivitiTaskList = wAPIResult.List(BPMActivitiTask.class);
            List<Integer> wNotifyUserIDList = new ArrayList<>();
            if (wAPIResult.getReturnObject().containsKey("NotifyList")) {
                wNotifyUserIDList = StringUtils
                        .parseIntList(wAPIResult.getReturnObject().get("NotifyList").toString().split(","));
            }

            List<BFCMessage> wBFCMessageList = new ArrayList<>();
            BFCMessage wBFCMessage = null;
            BFCMessage wBFCMessageClone = null;

            List<String> wStatusList = StringUtils.parseList(StringUtils.split(wBPMTaskBase.StatusText, ","));
            if (wStatusList.contains("待" + wSelfTask.Name) && wBPMActivitiTaskList.size() > 0)
                wStatusList.remove("待" + wSelfTask.Name);

            if (wBPMActivitiTaskList.size() > 0) {
                wStatusList.removeIf(p -> wBPMActivitiTaskList.stream().noneMatch(q -> p.equals("待" + q.Name)));
            }

            if (wBPMTaskBase.FollowerID.contains(wLoginUser.getID())) {
                wBPMTaskBase.FollowerID.remove(Integer.valueOf(wLoginUser.getID()));
            }
            List<Integer> wUserIDList = null;
            for (BPMActivitiTask bpmActivitiTask : wBPMActivitiTaskList) {
                if (bpmActivitiTask == null) {
                    continue;
                }

                wBFCMessage = new BFCMessage();
                wBFCMessage.Active = 0;
                wBFCMessage.CompanyID = wLoginUser.getCompanyID();
                wBFCMessage.MessageID = wBPMTaskBase.getID();
                wBFCMessage.ModuleID = wBPMTaskBase.getFlowType();
                wBFCMessage.Type = BFCMessageType.Task.getValue();
                wBFCMessage.ShiftID = 0;
                wBFCMessage.StepID = StringUtils.parseInt(bpmActivitiTask.ID);
                wBFCMessage.Title = StringUtils.Format("{0}", wBPMTaskBase.Code);
                wBFCMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1}  发起时刻：{2} 待{3}",
                                BPMEventModule.getEnumType(wBPMTaskBase.getFlowType()).getLabel(),
                                wBPMTaskBase.UpFlowName,
                                StringUtils.parseCalendarToString(wBPMTaskBase.CreateTime, "yyyy-MM-dd HH:mm"),
                                bpmActivitiTask.Name)
                        .trim();
                wBFCMessage.CreateTime = Calendar.getInstance();

                if (StringUtils.isEmpty(bpmActivitiTask.Assignee))
                    bpmActivitiTask.Assignee = "";
                if (StringUtils.isEmpty(bpmActivitiTask.Recipients))
                    bpmActivitiTask.Recipients = "";
                wUserIDList = StringUtils.parseIntList(bpmActivitiTask.Assignee.split(","));
                List<Integer> wRecipientList = StringUtils.parseIntList(bpmActivitiTask.Recipients.split(","));
                wRecipientList.removeAll(wUserIDList);

                for (Integer wResponsorID : wUserIDList) {
                    if (wResponsorID <= 0) {
                        if (wResponsorID != BMSEmployee.SysAdmin.getID())
                            continue;
                        wBPMTaskBase.setStepID(StringUtils.parseInt(bpmActivitiTask.ID));

//                        APSConstans.SetBizTask(wBPMTaskBase);
                    } else {
                        wBFCMessageClone = CloneTool.Clone(wBFCMessage, BFCMessage.class);
                        wBFCMessageClone.ResponsorID = wResponsorID;
                        wBFCMessageList.add(wBFCMessageClone);
//						WDWConstans.SetBizTask(wBPMTaskBase);
                    }
                }
                for (Integer wResponsorID : wRecipientList) {
                    if (wResponsorID <= 0) {
                        continue;
                    }
                    wBFCMessage.Type = BFCMessageType.Notify.getValue();
                    wBFCMessageClone = CloneTool.Clone(wBFCMessage, BFCMessage.class);
                    wBFCMessageClone.ResponsorID = wResponsorID;
                    wBFCMessageList.add(wBFCMessageClone);
                }

                wNotifyUserIDList.removeAll(wUserIDList);
                wNotifyUserIDList.removeAll(wRecipientList);

                wBPMTaskBase.FollowerID.addAll(wUserIDList);
                if (wUserIDList.size() == 0 && wUserIDList.contains(BMSEmployee.SysAdmin.getID()))
                    continue;
                if (!wStatusList.contains("待" + bpmActivitiTask.Name)) {
                    wStatusList.add("待" + bpmActivitiTask.Name);
                }
            }
            wBPMTaskBase.StatusText = StringUtils.Join(",", wStatusList);
            if (StringUtils.isEmpty(wBPMTaskBase.StatusText)) {
                wBPMTaskBase.StatusText = "已" + wSelfTask.Name;
            }
            if (wNotifyUserIDList.size() > 0) {
                for (Integer wResponsorID : wNotifyUserIDList) {
                    wBFCMessage = new BFCMessage();
                    wBFCMessage.Active = 0;
                    wBFCMessage.CompanyID = wLoginUser.getCompanyID();
                    wBFCMessage.MessageID = wBPMTaskBase.getID();
                    wBFCMessage.ModuleID = wBPMTaskBase.getFlowType();
                    wBFCMessage.Type = BFCMessageType.Notify.getValue();
                    wBFCMessage.ShiftID = 0;
                    wBFCMessage.StepID = StringUtils.parseInt(wSelfTask.ID);
                    wBFCMessage.Title = StringUtils.Format("{0}", wBPMTaskBase.Code);
                    wBFCMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1} 发起时刻：{2}  已{3}",
                            BPMEventModule.getEnumType(wBPMTaskBase.getFlowType()).getLabel(),
                            wBPMTaskBase.UpFlowName,
                            StringUtils.parseCalendarToString(wBPMTaskBase.CreateTime, "yyyy-MM-dd HH:mm"),
                            wSelfTask.Name);
                    wBFCMessage.ResponsorID = wResponsorID;
                    wBFCMessage.CreateTime = Calendar.getInstance();
                    wBFCMessageList.add(wBFCMessage);
                }

            }

            BFCServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
        } catch (Exception e) {
            wResult.FaultCode += e.getMessage();
            logger.error("BPM_MsgUpdate", e);
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> BPM_CreateToDoMessage(BMSEmployee wLoginUser, int wFlowID, int wTaskID,
                                                        int wModuleID, String wCode) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            // ①查询流程历史
            List<BPMActivitiHisTask> wNewTaskList = BPMServiceImpl.getInstance()
                    .BPM_GetHistoryInstanceByID(BMSEmployee.SysAdmin, wFlowID).List(BPMActivitiHisTask.class);
            if (wNewTaskList == null || wNewTaskList.size() <= 0) {
                return wResult;
            }
            // ②根据StepID查询消息是否已生成
            if (StringUtils.isEmpty(wNewTaskList.get(0).Assignee)) {
                return wResult;
            }
            String[] wStrs = wNewTaskList.get(0).Assignee.split(",");
            int wApplyer = StringUtils.parseInt(wStrs[0]);

            BMSEmployee wAppUser = new BMSEmployee();
            if (wApplyer > 0) {
                Map<String, Object> wParams = new HashMap<String, Object>();
                wParams.put("ID", wApplyer);
                wAppUser = ORMUtils.GetPoService(BMSEmployee.class).SelectPO(wLoginUser, wParams, wErrorCode);
            }

            // ③若没生成，生成待办消息
            List<BPMActivitiHisTask> wToTaskList = wNewTaskList.stream().filter(p -> p.Status == 0)
                    .collect(Collectors.toList());
            if (wToTaskList.size() <= 0) {
                return wResult;
            }
            if (StringUtils.isEmpty(wToTaskList.get(0).Assignee)) {
                return wResult;
            }

            for (BPMActivitiHisTask wBPMActivitiHisTask : wToTaskList) {
                int wStepID = StringUtils.parseInt(wBPMActivitiHisTask.ID);
                if (wStepID <= 0) {
                    continue;
                }

                boolean wFlag = BFCMessageDAO.getInstance().IsMessageExist(wLoginUser, wStepID, wErrorCode);
                if (wFlag) {
                    continue;
                }

                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage = null;
                SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                int wShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));
                for (String wItem : wBPMActivitiHisTask.Assignee.split(",")) {
                    int wUser = StringUtils.parseInt(wItem);
                    if (wUser <= 0) {
                        continue;
                    }
                    wMessage = new BFCMessage();
                    wMessage.Active = 0;
                    wMessage.CompanyID = 0;
                    wMessage.CreateTime = Calendar.getInstance();
                    wMessage.EditTime = Calendar.getInstance();
                    wMessage.ID = 0;
                    wMessage.MessageID = wTaskID;
                    wMessage.Title = wCode;
                    wMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1}  发起时刻：{2} 待{3}",
                                    BPMEventModule.getEnumType(wModuleID).getLabel(),
                                    wAppUser.Name,
                                    StringUtils.parseCalendarToString(wBPMActivitiHisTask.StartTime, "yyyy-MM-dd " +
                                            "HH:mm"),
                                    wBPMActivitiHisTask.Name)
                            .trim();
                    wMessage.ModuleID = wModuleID;
                    wMessage.ResponsorID = wUser;
                    wMessage.ShiftID = wShiftID;
                    wMessage.StepID = StringUtils.parseInt(wBPMActivitiHisTask.ID);
                    wMessage.StationID = 0;
                    wMessage.Type = BFCMessageType.Task.getValue();
                    wBFCMessageList.add(wMessage);
                }
                BFCServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.getMessage();
            logger.error(e.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetInstanceByID(BMSEmployee wLoginUser, int wFlowID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processInstanceId", wFlowID);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiProcessInstanceByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetHistoryInstanceByID(BMSEmployee wLoginUser, int processInstanceId) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processInstanceId", processInstanceId);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiHisTaskByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_DeleteInstanceByID(BMSEmployee wLoginUser, int wFlowID, String wReason) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processInstanceId", wFlowID + "");
            wParams.put("deleteReason", wReason);
            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/deleteProcessInstance?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public APIResult BPM_GetActivitiHisTaskByPIId(BMSEmployee wLoginUser, int wFlowID) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<>();
            wParams.put("processInstanceId", wFlowID + "");
            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/History/getBPMActivitiHisTaskByPIId?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.GET);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    //region 指定驳回
    @Override
    public APIResult BPM_RejectedSpecifiedActivity(BMSEmployee wLoginUser, String wTaskID, String targetActivityId,
                                                   Object wData) {
        APIResult wResult = new APIResult();
        try {
            Map<String, Object> wParams = new HashMap<String, Object>();

            wParams.put("TaskID", wTaskID);
            wParams.put("targetActivityId", targetActivityId);
            wParams.put("data", wData);

            wResult = RemoteInvokeUtils.getInstance().HttpInvokeAPI(ServerUrl, ServerName,
                    StringUtils.Format("api/Runtime/rejectedSpecifiedActivity?cadv_ao={0}&cade_po={1}",
                            wLoginUser.getLoginName(), wLoginUser.getPassword()),
                    wParams, HttpMethod.POST);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<Object> BPM_RejectTo(BMSEmployee wLoginUser, String wTaskID, String targetActivityId,
                                              Object wData, String targetActivityName, int wFlowType) {
        ServiceResult<Object> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            Map<String, Object> wDataMap = (Map<String, Object>) wData;
            List<BPMActivitiHisTask> wHisList = new ArrayList<>();
            if (wDataMap.containsKey("FlowID")) {
                wHisList = BPMServiceImpl.getInstance()
                        .BPM_GetHistoryInstanceByID(wLoginUser, StringUtils.parseInt(wDataMap.get("FlowID")))
                        .List(BPMActivitiHisTask.class);
            }

            // ①调用bpm服务驳回操作
            if (wHisList.stream().anyMatch(p -> p.ActivitiID.equals("RelevantDepartments_review"))) {
                List<BPMActivitiHisTask> wToCloseTaskList = wHisList.stream()
                        .filter(p -> p.ActivitiID.equals("RelevantDepartments_review")
                                && p.Status == 0 && !p.ID.equals(wTaskID))
                        .collect(Collectors.toList());
                Map<String, Object> wObjMap = CloneTool.Clone(wData, Map.class);
                if (wObjMap.containsKey("Remark")) {
                    wObjMap.put("Remark", "");
                }
                if (wObjMap.containsKey("Remark_txt_")) {
                    wObjMap.put("Remark_txt_", "");
                }
                for (BPMActivitiHisTask wBPMActivitiHisTask : wToCloseTaskList) {
                    Map<String, Object> wParams = new HashMap<String, Object>();
                    BMSEmployee wUser = ORMUtils.GetPoService(BMSEmployee.class).SelectPO(wLoginUser, wParams,
                            wErrorCode);
                    if (wUser != null && wUser.ID > 0) {
                        wUser.LoginName = DesUtil.encrypt(wUser.LoginName, SessionConstants.appSecret);
                        BPMServiceImpl.getInstance().BPM_RejectedSpecifiedActivity(wUser, wBPMActivitiHisTask.ID,
                                targetActivityId, wObjMap);
                    }
                }
            }
            APIResult wAPIResult = BPMServiceImpl.getInstance().BPM_RejectedSpecifiedActivity(wLoginUser, wTaskID,
                    targetActivityId, wData);
            if (wAPIResult == null) {
                wResult.FaultCode += "提示：驳回失败，BPM服务返回空!";
                return wResult;
            }
            if (wAPIResult.getResultCode() != 1000) {
                wResult.FaultCode += "提示：驳回失败。" + wAPIResult.getMsg();
                return wResult;
            }
            // ②更新主业务单据状态
            int wMessageID = 0;
            String wUpFlowName = "";
            String wCode = "";
            Calendar wCreateTime = Calendar.getInstance();

            BPMEventModule wEventID = BPMEventModule.getEnumType(wFlowType);
            if (!Constants.BPMServiceMap.containsKey(wEventID)) {
                wResult.FaultCode += "该流程暂不支持";
                return wResult;
            }
            BPMTaskService wBPMTaskService = Constants.BPMServiceMap.get(wEventID);

            PoService wPoService = ORMUtils.GetPoService(wBPMTaskService.GetTClass());

            BPMTaskBase wTask = (BPMTaskBase) CloneTool.Clone(wData, wBPMTaskService.GetTClass());


            if (wTask == null || wTask.ID <= 0) {
                wResult.FaultCode += "提示：data数据转换失败!";
                return wResult;
            }
            wTask.StatusText = "待" + targetActivityName;
            wPoService.UpdatePo(wLoginUser, wTask, wErrorCode);

            // ①更新数据
            wMessageID = wTask.ID;
            wUpFlowName = wTask.UpFlowName;
            wCode = wTask.Code;
            wCreateTime = wTask.CreateTime;

            // ③创建待办信息
            if (wDataMap.containsKey("FlowID")) {
                wHisList = BPMServiceImpl.getInstance()
                        .BPM_GetHistoryInstanceByID(wLoginUser, StringUtils.parseInt(wDataMap.get("FlowID")))
                        .List(BPMActivitiHisTask.class);
            }
            wHisList = wHisList.stream().filter(p -> p.Status == 0).collect(Collectors.toList());
            if (wHisList.size() > 0) {
                BPMActivitiHisTask wHis = wHisList.get(0);
                String[] wStrs = wHis.Assignee.split(",");

                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage;
                SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                int wShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));
                for (String wStr : wStrs) {
                    int wUserID = StringUtils.parseInt(wStr);
                    // 发送任务消息到人员
                    wMessage = new BFCMessage();
                    wMessage.Active = 0;
                    wMessage.CompanyID = 0;
                    wMessage.CreateTime = Calendar.getInstance();
                    wMessage.EditTime = Calendar.getInstance();
                    wMessage.ID = 0;
                    wMessage.MessageID = wMessageID;
                    wMessage.StepID = StringUtils.parseInt(wHis.ID);
                    wMessage.Title = StringUtils.Format("{0}", wCode);
                    wMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1}  发起时刻：{2} 待{3}",
                                    BPMEventModule.getEnumType(wFlowType).getLabel(), wUpFlowName,
                                    StringUtils.parseCalendarToString(wCreateTime, "yyyy-MM-dd HH:mm"),
                                    wHis.Name)
                            .trim();
                    wMessage.ModuleID = wFlowType;
                    wMessage.ResponsorID = wUserID;
                    wMessage.ShiftID = wShiftID;
                    wMessage.StationID = 0;
                    wMessage.Type = BFCMessageType.Task.getValue();
                    wBFCMessageList.add(wMessage);
                }
                BFCServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
            }

            //完成待办
            BFCService.mBFCHandleTaskMessageResource.add(new BFCHandleTaskMessage(wLoginUser, wLoginUser.ID,
                    StringUtils.parseListArgs(wMessageID), wFlowType,
                    StringUtils.parseInt(wTaskID), BFCMessageStatus.Finished.getValue(), 1,wTask.CreateTime));

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.getMessage();
            logger.error("BPM_RejectTo",e);
        }
        return wResult;
    }

    @Override
    public ServiceResult<Integer> BPM_SynchronizUser(BMSEmployee wLoginUser) {
        ServiceResult<Integer> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            Map<String, Object> wParams = new HashMap<String, Object>();

            List<BMSEmployee> wBMSEmployeeList = mBMSEmployeeService.SelectPOList(wLoginUser, wParams,
                    Pagination.getMaxSize(), wErrorCode);
            if (wBMSEmployeeList == null || wBMSEmployeeList.size() == 0) {
                wResult.FaultCode += "提示：用户信息查询失败!";
                return wResult;
            }

            BPMUserDAO.getInstance().TruncateGroup(wLoginUser, wErrorCode);
            BPMUserDAO.getInstance().TruncateUser(wLoginUser, wErrorCode);

            BPMUser wBPMUser;
            for (BMSEmployee wBMSEmployee : wBMSEmployeeList) {
                wBPMUser = new BPMUser();
                wBPMUser.ID_ = String.valueOf(wBMSEmployee.ID);
                wBPMUser.REV_ = 1;
                wBPMUser.FIRST_ = wBMSEmployee.Name;
                mBPMUserService.UpdatePo(wLoginUser, wBPMUser, wErrorCode);
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.getMessage();
            logger.error(e.toString());
        }
        return wResult;
    }

    //endregion
}
